package com.cartrentalsystem.service.impl;

import com.cartrentalsystem.context.BaseContext;
import com.cartrentalsystem.domain.po.Customers;
import com.cartrentalsystem.domain.po.Rental;
import com.cartrentalsystem.domain.po.Report;
import com.cartrentalsystem.service.ICustomersService;
import com.cartrentalsystem.service.IRentalService;
import com.cartrentalsystem.service.IUserService;
import com.cartrentalsystem.service.ReportService;
import com.cartrentalsystem.utils.TimeUtils;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class ReportServiceImpl implements ReportService {

    private final IRentalService rentalService;

    private final ICustomersService customersService;

    private final IUserService userService;


    @Override
    public void export(HttpServletResponse response){
        Integer userId = Math.toIntExact(BaseContext.getCurrentId());
        String name = userService.getById(userId).getName();

        LocalDate today = LocalDate.now();

        List<Rental> list = rentalService.lambdaQuery()
                .eq(Rental::getStatus, 2)
                .eq(Rental::getDeleted, 0)
                .lt(Rental::getRealReturnTime, TimeUtils.getLastDayOfMonth(today))
                .gt(Rental::getRealReturnTime, TimeUtils.getFirstDayOfMonth(today))
                .list();

        // 获取所有客户id
        Set<Integer> collect = list.stream().map(Rental::getCustomerId).collect(Collectors.toSet());

        // 获取所有客户id对应的金额
        Map<Integer,Double> map = new HashMap<>();
        for (Integer customerId : collect) {
            map.put(customerId, list.stream().filter(rental -> rental.getCustomerId().equals(customerId)).mapToDouble(Rental::getMoney).sum());
        }

        List<Report> reportList = new ArrayList<>();
        for (Integer customerId : collect) {
           Report report = new Report();
           Customers customer = customersService.getById(customerId);
           report.setCustomerName(customer.getName());
           report.setRentalTimes(customer.getRentalTimes());
           report.setTotalRentalAmount(map.get(customerId));
           reportList.add(report);
        }

        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/数据报表.xlsx");

        // 创建一个工作簿
        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            Sheet sheet = excel.getSheet("rental_report");

            Row row = sheet.getRow(3);
            LocalDateTime startTime = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String time = startTime.format(formatter);
            row.createCell(8).setCellValue(time);

            row = sheet.getRow(5);
            row.createCell(8).setCellValue(name);

            for (int i = 0; i < reportList.size(); i++) {
                row = sheet.createRow(7+i);
                row.createCell(7).setCellValue(reportList.get(i).getCustomerName());
                row.createCell(8).setCellValue(reportList.get(i).getRentalTimes());
                row.createCell(9).setCellValue(reportList.get(i).getTotalRentalAmount());
            }

            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            outputStream.close();
            excel.close();
        }
        catch (Exception e) {
            log.error("创建工作簿失败", e);
        }

    }
}
